#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIMBO 700
#define N_PAL_RESERVADAS 34
#define N_TIPOS 30
#define MAX_TAM_TIPOS 20
#define MAX_TAM_VAR 10

#define ERRO_TIPO_DADO 150
#define ERRO_IDENT_GRANDE 151
#define ERRO_IDENT_NDECL 152
#define ERRO_CADEIA_INVA 153


//Estrutura dos símbolos...
typedef struct simbolos{
	char *id;
	char *tipo;
	int valor;
	int end;
	
} simbo;

char **auxVar;
int total = 0;
char indices[50];

char **auxTipo;
int indCount = 0;

char **auxOp;
int opCount = 0;

//Tabela de palavras reservadas

//Inicializa a tabela de palavras reservadas
void inicializaPalavrasReservadas(char res[26][30]){

	strcpy(res[1], "begin");	
	strcpy(res[2], "const");
	strcpy(res[3], "do");
	strcpy(res[4], "else");
	strcpy(res[5], "end");
	strcpy(res[8], "if");
	strcpy(res[9], "integer");
	strcpy(res[16], "program");
	strcpy(res[17], "procedure");
	strcpy(res[18], "real");
	strcpy(res[19], "repeat");
	strcpy(res[20], "readln");
	strcpy(res[21], "then");
	strcpy(res[22], "until");
	strcpy(res[23], "var");
	strcpy(res[24], "while");	
	strcpy(res[25], "writeln");

	auxVar = (char **)malloc(MAX_SIMBO * sizeof(char*));
	int i;
	for(i = 0; i < MAX_SIMBO; i++){
		auxVar[i] = (char *)malloc(MAX_TAM_VAR * sizeof(char));
	}

	auxTipo = (char **)malloc(100 * sizeof(char*));
	for(i = 0; i < 100; i++){
		auxTipo[i] = (char *)malloc(MAX_TAM_VAR * sizeof(char));
	}

	auxOp = (char **)malloc(40 * sizeof(char*));
	for(i = 0; i < 40; i++){
		auxOp[i] = (char *)malloc(sizeof(char));
	}
		
	return;
}

//Aplicação da função hash para buscar uma palavra reservada
int buscaPalavraReservada(char res[26][30], simbo fator, int *tag, int *pal_reser){

	int i = fator.id[0] - 97;
	int cod = i;

	while((i < 26) || (res[i][0] == fator.id[0])){
		if(strcmp(res[i], fator.id) == 0){
			if(i == 23 || i == 16)
				*tag = 1;
			*pal_reser = i;
			return 1;
		}
		i++;
	}
	return 0;
}

void liberaVar(){
	
	total = 0;

}

//Tabela de símbolos

//Busca por elemento na tabela de símbolos
int buscaElem(simbo *simb, char *ide, int n, int *indice){

int i;
	for(i  = 0; i < n; i++){		
		if(strcmp(simb[i].id, ide) == 0){
				*indice = i;
				return 1;
		}
	}
	return 0;
}

int segurada(char *id){

int i;
	for(i  = 0; i < total; i++){		
		if(strcmp(auxVar[i], id) == 0){
				return 1;
		}
	}
	return 0;

}

void seguraVar(char *id){

	strcpy(auxVar[total], id);
	total++;
}

void seguraIndiceTipo(simbo *tab_sim, int indice){

	indices[indCount] = indice;
	strcpy(auxTipo[indCount], tab_sim[indice].tipo);
	indCount++;

}

void seguraOp(char op){

	auxOp[opCount][0] = op;
	opCount++;	

}

int verificaTipo(char *tipo){

	int i;
	if(strcmp(tipo, "integer") == 0){
		for(i = 0; i < indCount; i++){
			if(strcmp(auxTipo[i], "real") == 0)
				return 0;
		}
	}

	return 1;


}

//Adiciona um elemento na tabela de símbolos
int adicionarSimb(simbo *simb, char *ide, int *numElem, char *tipo){
		
	if((*numElem) >= MAX_SIMBO)
		return 0;

	simb[*numElem].id = (char *)malloc(sizeof(char));
	strcpy(simb[*numElem].id, ide);

	simb[*numElem].tipo = (char *)malloc(sizeof(char));
	strcpy(simb[*numElem].tipo, tipo);
	
	*numElem = *numElem + 1;
	
	return 1;
}

int atualizaTabela(simbo *simb, int *numElem, char *tipo){

	int i;
	for(i = 0; i < total; i++){
		if(!adicionarSimb(simb, auxVar[i], numElem, tipo))
			return 0;
	}
	return 1;
}



//Tabela de tipo de dados

//Busca na tabela de tipos de dados
int buscaTipo(char tab[N_TIPOS][MAX_TAM_TIPOS], char *fator, int n){

int i;
	for(i = 0; i < n; i++){
		if(strcmp(tab[i], fator) == 0)
			return i;
	}
	
	return -1;
}

//Inicializa a tabela de tipo de dados
void inicializaTipo(char tab[N_TIPOS][MAX_TAM_TIPOS]){

int i;

	strcpy(tab[0], "integer");
	strcpy(tab[1], "real");
	
}




